;Generate table of frequencies
math round off
!12_degree_root_of_2 #= 1.0594630943593; For equal-tempered semitones
!ntsc_nes_cpu_hertz_speed #= 1790000
!pal_nes_cpu_hertz_speed #= 1662607
!dendy_nes_cpu_hertz_speed #= 1773448
!frequency #= 440/8 ; Starting frequency of the table
!note_offset #= 0
while !note_offset <= 8 ; Displace starting frequency of the table to start in a C note 
!frequency #= !frequency/!12_degree_root_of_2
!note_offset #= !note_offset+1
endif
!table_entry_index #= 0
frequency_table:
while !table_entry_index < 12*8
;print "!frequency"
dw round((!ntsc_nes_cpu_hertz_speed/(!frequency*16))-1,0)
!frequency #= !frequency*!12_degree_root_of_2
!table_entry_index #= !table_entry_index+1
endif

;Generate constant symbols for note names
!note_base_index #= $00
macro generate_note_table(octave)
!Cb<octave> #= !note_base_index-1
!C<octave>  #= !note_base_index
!Cs<octave> #= !note_base_index+1
!Db<octave> #= !note_base_index+1
!D<octave>  #= !note_base_index+2
!Ds<octave> #= !note_base_index+3
!Eb<octave> #= !note_base_index+3
!E<octave>  #= !note_base_index+4
!Es<octave> #= !note_base_index+5
!Fb<octave> #= !note_base_index+4
!F<octave>  #= !note_base_index+5
!Fs<octave> #= !note_base_index+6
!Gb<octave> #= !note_base_index+6
!G<octave>  #= !note_base_index+7
!Gs<octave> #= !note_base_index+8
!Ab<octave> #= !note_base_index+8
!A<octave>  #= !note_base_index+9
!As<octave> #= !note_base_index+10
!Bb<octave> #= !note_base_index+10
!B<octave>  #= !note_base_index+11
!Bs<octave> #= !note_base_index+12
endmacro
!octave_number #= 1
while !octave_number <= 8
%generate_note_table(!octave_number)
!note_base_index #= !note_base_index+12
!octave_number #= !octave_number+1
endif

;Commands
track_effect_jump_table:
dw end_of_stream_data_effect : !END_OF_STREAM_DATA = #$80
dw rest_effect : !REST = #$81 ;Silences note
dw tie_effect : !TIE = #$82 ;Continues playing note
dw loop_effect : !LOOP = #$83 ;Sets loop point

;Volume envelopes
audio_volume_envelope_jump_table:
dw volume_envelope_0
dw volume_envelope_1
dw volume_envelope_2
volume_envelope_0:
db $0f
db $ff
volume_envelope_1:
db $0f, $0e, $0d, $0b, $08, $04, $00
db $ff
volume_envelope_2:
db $01, $02, $03, $05, $08, $0c, $0f
db $ff



!speed_command_index_number #= 1
macro generate_note_speed(speed_command_index)
!SPEED_<speed_command_index> #= $80-!speed_command_index_number
endmacro
while !speed_command_index_number <= 32
%generate_note_speed(!speed_command_index_number)
!speed_command_index_number #= !speed_command_index_number+1
endif

!RP2A0X_SQR_CHANNEL = #$00
!RP2A0X_SQR2_CHANNEL = #$01
!RP2A0X_TRI_CHANNEL = #$02
!RP2A0X_NOI_CHANNEL = #$03

audio_track_header_pointer_table:
dw audio_track0_header
dw audio_track1_header
dw audio_track2_header
dw audio_track3_header

audio_track0_header:
db !RP2A0X_SQR_CHANNEL ; Channel to send data at
db %10111111 ; Duty/Decay/Volume initial values, in aabbcccc format, respectively.
db %00000000 ; Initial volume envelope stream
db %10000000 ; Initial tempo
dw audio_track0_stream0 ; Address of stream data
db !RP2A0X_SQR2_CHANNEL ; Channel to send data at
db %10111111 ; Duty/Decay/Volume initial values, in aabbcccc format, respectively.
db %00000000 ; Initial volume envelope stream
db %10000000 ; Initial tempo
dw audio_track0_stream1 ; Address of stream data
db $ff ; End of header data

audio_track0_stream0:
db !SPEED_16, !LOOP

;First section
db !B4,!Cs5,!Ds5,!Fs5
db !B4,!Cs5,!Ds5,!G5
db !B4,!Cs5,!Ds5,!E5
db !Fs5,!Gs5,!Fs5,!Ds5

db !B4,!Cs5,!Ds5,!Cs5
db !B4,!Cs5,!Ds5,!G5
db !B4,!Cs5,!Ds5,!E5
db !Fs5,!Gs5,!A5,!As5

;Second section
db !B5,!Cs6,!As5,!Gs5
db !Fs5,!Gs5,!As5,!TIE
db !E5,!Fs5,!Gs5,!TIE
db !Ds5,!E5,!Fs5,!Gs5

db !B5,!Cs6,!As5,!Gs5
db !Fs5,!Gs5,!As5,!Ds5
db !E5,!Fs5,!Gs5,!TIE
db !Fs5,!TIE,!TIE,!TIE

db !END_OF_STREAM_DATA

audio_track0_stream1:
db !SPEED_16, !LOOP
;First section
db !B2,!Ds3,!Fs3,!TIE
db !B2,!Ds3,!G3,!TIE
db !B2,!Ds3,!Gs3,!TIE
db !B2,!Ds3,!G3,!TIE

db !B2,!Ds3,!Fs3,!TIE
db !B2,!Ds3,!G3,!TIE
db !B2,!Ds3,!Gs3,!TIE
db !B2,!Ds3,!A3,!TIE

;Second section
db !E3,!Gs3,!B3,!TIE
db !Ds3,!Fs3,!As3,!TIE
db !Cs3,!E3,!Gs3,!TIE
db !B2, !Ds3, !Fs3, !TIE

db !E3,!Gs3,!B3,!TIE
db !Ds3,!Fs3,!As3,!TIE
db !Cs3,!E3,!Gs3,!TIE
db !B2, !Ds3, !Fs3, !TIE
db !END_OF_STREAM_DATA

audio_track1_header:
db !RP2A0X_SQR_CHANNEL ; Channel to send data at
db %00000001 ; Status byte
db %10111111 ; Duty/Decay/Volume initial values, in aabbcccc format, respectively.
db %00000001 ; Initial volume envelope stream
db %01000000 ; Initial tempo
dw audio_track1_stream0 ; Address of stream data
db !RP2A0X_SQR2_CHANNEL ; Channel to send data at
db %00000001 ; Status byte
db %10111111 ; Duty/Decay/Volume initial values, in aabbcccc format, respectively.
db %00000010 ; Initial volume envelope stream
db %01000000 ; Initial tempo
dw audio_track1_stream1 ; Address of stream data
db !RP2A0X_TRI_CHANNEL ; Channel to send data at
db %00000001 ; Status byte
db %10111111 ; Volume
db %00000001 ; Initial volume envelope stream
db %01000000 ; Initial tempo
dw audio_track1_stream2 ; Address of stream data
db !RP2A0X_NOI_CHANNEL ; Channel to send data at
db %00000000 ; Status byte
db $ff ; End of header data
audio_track1_stream0:
db !SPEED_1,!G6,!SPEED_32,!C6,!E6,!G6,!C6,!E6,!G6,!C6,!E6,!G6,!REST
db !END_OF_STREAM_DATA
audio_track1_stream1:
db !SPEED_16,!E6,!REST
db !END_OF_STREAM_DATA
audio_track1_stream2:
db !SPEED_15,!C6,!REST
db !END_OF_STREAM_DATA

audio_track2_header:
db !RP2A0X_TRI_CHANNEL ; Channel to send data at
db %10111111 ; Volume
db %00000000 ; Initial volume envelope stream
db %10000000 ; Initial tempo
dw audio_track2_stream0 ; Address of stream data
db $ff ; End of header data
audio_track2_stream0:
db !SPEED_24,!C6,!E6,!G6,!C7
db $ff

audio_track3_header:
db !RP2A0X_SQR_CHANNEL ; Channel to send data at
db %10001111 ; Duty/Decay/Volume initial values, in aabbcccc format, respectively.
db %00000001 ; Initial volume envelope stream
db %10000000 ; Initial tempo
dw audio_track3_stream0 ; Address of stream data
db !RP2A0X_SQR2_CHANNEL ; Channel to send data at
db %10111111 ; Duty/Decay/Volume initial values, in aabbcccc format, respectively.
db %00000000 ; Initial volume envelope stream
db %10000000 ; Initial tempo
dw audio_track3_stream1 ; Address of stream data
db !RP2A0X_TRI_CHANNEL ; Channel to send data at
db %10111111 ; Volume
db %00000000 ; Initial volume envelope stream
db %10000000 ; Initial tempo
dw audio_track3_stream2 ; Address of stream data
db $ff ; End of header data

audio_track3_stream0:
db !SPEED_8, !LOOP




;First section
db !B3, !C5

db !END_OF_STREAM_DATA

audio_track3_stream1:
db !SPEED_16, !LOOP
;First section
db !REST

db !END_OF_STREAM_DATA


audio_track3_stream2:
db !SPEED_8, !LOOP
;First section
db !REST
db !END_OF_STREAM_DATA
